function low(v) {
  v = parseInt(v * 100 + 0.5)
  return v & 0xFF
}

function hig(v) {
  v = parseInt(v * 100 + 0.5)
  return (v >> 8) & 0xFF
}

function low_r(v) {
  return v & 0xFF
}

function hig_r(v) {
  return (v >> 8) & 0xFF
}

function encryptStr({ cmdHead = 0x23, weight = 0, mac = '' , resistance = 0, resistance500 = 0, left_weight = 0, heart = 0}) {
  let macArr = mac.split(':')
  let mac1 = macArr.slice(0, 3).map(item => +`0x${item}`).join(' ')
  let mac2 = macArr.slice(3).map(item => +`0x${item}`).join(' ')
  let w_low = low(weight)
  let w_hig = hig(weight)
  let r_low = low_r(resistance)
  let r_hig = hig_r(resistance)
  let r_500_low = low_r(resistance500)
  let r_500_hig = hig_r(resistance500)
  let l_w_low = low(left_weight)
  let l_w_hig = hig(left_weight)
  let d1 = parseInt(Math.random() * 99)
  let d2 = parseInt(Math.random() * 99)
  let d3 = parseInt(Math.random() * 99)
  let str = `${cmdHead} ${mac1} ${d1} ${mac2} ${w_hig} ${w_low} ${r_hig} ${r_low} ${d2} ${r_500_hig} ${r_500_low} ${l_w_low} ${l_w_hig} ${d3} ${heart}`
  let cmdData = str.split(' ')
  let checksum = 0

  cmdData = cmdData.map((item) => {
    checksum += +item
    return +item
  })
  checksum = checksum & 0xFF
  cmdData.push(checksum)

  function odd(arr) {//奇数组
    return [arr[2], arr[0], arr[3], arr[1]]
  }

  function even(arr) {//偶数组
    return [arr[3], arr[0], arr[1], arr[2]]
  }

  let arr1 = odd(cmdData.slice(0, 4))
  let arr2 = even(cmdData.slice(4, 8))
  let arr3 = odd(cmdData.slice(8, 12))
  let arr4 = even(cmdData.slice(12, 16))
  let arr5 = odd(cmdData.slice(16, 20))

  let transtionArr1 = [0x43, 0x4A, 0x58, 0x4C]
  let transtionArr2 = [0x57, 0x46, 0x53, 0x4D]

  function transtion(arr, transtionArr) {
    return arr.map((t, i) => t ^ transtionArr[i])
  }

  function mergeArray(arr) {
    return (arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]
  }

  function fomate2Btye(b) {
    let str = b.toString(16)
    while (str.length < 4) {
      str = '0' + str
    }
    return str
  }

  function move(tmp) {
    const t1 = (tmp << 17) & 0xFFFFFFFF
    const t2 = (tmp >> 15) & 0x1FFFF
    const result = (t1 | t2)
    const high = (result >> 16) & 0xFFFF
    const low = result & 0xFFFF

    return fomate2Btye(high) + fomate2Btye(low)
  }

  let newArr1 = transtion(arr1, transtionArr1)
  let newArr2 = transtion(arr2, transtionArr2)
  let newArr3 = transtion(arr3, transtionArr1)
  let newArr4 = transtion(arr4, transtionArr2)
  let newArr5 = transtion(arr5, transtionArr1)

  newArr1 = mergeArray(newArr1)
  newArr2 = mergeArray(newArr2)
  newArr3 = mergeArray(newArr3)
  newArr4 = mergeArray(newArr4)
  newArr5 = mergeArray(newArr5)

  newArr1 = move(newArr1)
  newArr2 = move(newArr2)
  newArr3 = move(newArr3)
  newArr4 = move(newArr4)
  newArr5 = move(newArr5)

  let tmpCmdData = cmdData.map(item => {
    let str = item.toString(16)
    return (str.length < 2 ? `0${str}` : str).toUpperCase()
  })

  return {
    originData: tmpCmdData.join(' '),
    str: (newArr1 + newArr2 + newArr3 + newArr4 + newArr5).toUpperCase()
  }
}

module.exports = {
  low,
  hig,
  encryptStr
}